package com.sensePlusVR.utils;

import android.annotation.SuppressLint;

import com.alibaba.fastjson.JSON;
import com.sensePlusVR.application.VRApplication;
import com.sensePlusVR.bean.BuriePointEventReqDto;
import com.sensePlusVR.bean.BuriedPointDLData;
import com.sensePlusVR.bean.CollectionItem;
import com.sensePlusVR.bean.GameItem;
import com.sensePlusVR.utils.DownloadBatchUrl.DownloadCallBack;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressLint("UseSparseArrays")
public class GameDownload {
	static private final String TAG = "GameDownload";

	// private Map<String, String> gameUrlMap;
	static private int FailtRetry = 100;
	static public int GameDownLoadStatDoing = 1;
	static public int GameDownLoadStatDone = 2;
	static public int GameDownLoadStatNeedDownload = 3;
	static public int GameDownLoadStatClicked = 4;
	static Object lock = new Object();
	static Map<Integer, DownloadTask> tasks = new HashMap<Integer, DownloadTask>();
	static Object nLock = new Object();

	//获取下载根目录
	public static String getRootPath(GameItem gameItem){
		return gameItem.getType().equals(Constant.TYPE_LIKEREAL)||gameItem.getType().equals(Constant.TYPE_DEMO_LIKEREAL)?getVirtualGameCacheDir():getRealGameCacheDir(gameItem.getTitle());
	}
	
	private static String getVirtualGameCacheDir() {
		return FileUtils.getExternalFilesDir(VRApplication.getAppContext()) + "/unReal";
	}
	
	private static String getRealGameCacheDir(String name){
		String gameDir = name.replaceAll("\\s*", "");
		return FileUtils.getExternalFilesDir(VRApplication.getAppContext()) + "/real/"+gameDir;
	}
	
	static public String getGameConfig(GameItem gameItem) {
		
		boolean isRealGame = gameItem.getType().equals(Constant.TYPE_DEMO_REAL)||gameItem.getType().equals(Constant.TYPE_REAL);
		String gameConfig = "";
		
		if (gameItem != null) {
			String gameUrl = gameItem.getGameurl();
			if(gameUrl != null){
				String[] fileNames = gameUrl.split(",");
				for (String fileName : fileNames) {
					if(fileName.endsWith("_script") || fileName.endsWith(".json")){
						gameConfig = getRootPath(gameItem) + File.separator + fileName;
						if(!isRealGame){
							
							gameConfig = "file://"+gameConfig;
						}
						
						break;	
					}
				}
			}
		}
		
		MyLog.d(TAG, "gameConfig : " + gameConfig);
		
		return gameConfig;
	}

	static public List<String> GameUrls(GameItem gameItem) {
		List<String> gameList = new ArrayList<String>();
		if (gameItem != null) {
			String gameUrl = gameItem.getGameurl();
			if(gameUrl != null){
				String[] urls = gameUrl.split(",");
				String prefix = gameItem.getPrefix();
				for (String url : urls) {
					gameList.add(prefix+url);
				}	
			}
		}
		return gameList;
	}
	
	/**
	 * 获取游戏资源
	 * @param gameItem
	 * @return
	 */
	private static List<String> GameRes(GameItem gameItem){
		
		List<String> resList = new ArrayList<String>();
		
		if (gameItem != null) {
			String gameUrl = gameItem.getGameurl();
			String[] urls = gameUrl.split(",");
			for (String url : urls) {
				resList.add(url);
			}
		}
		return resList;
	}
	

	public static void downloadGame(GameItem gameItem) {
		
		CollectionItem clcItem = CollectionItem.query(gameItem.getId());
		
		if(clcItem!=null){
			
			clcItem.setDownloadTime(new Date().getTime());
			
			clcItem.setDownloadState(CollectionItem.DownloadDoing);
			
			CollectionItem.saveOrUpdate(clcItem);
			
			//设置埋点初始值
			boolean isUpdate = false;
			
			MyLog.d("delBuride", "isUpdate : " + isUpdate + " clcItem id : " + clcItem.get_id());
			
			BuriePointEventReqDto buriePointEventReqDto = BuriePointEventReqDto.getBuriePointByClcItemId(clcItem.get_id());
			if(buriePointEventReqDto != null){
				Integer flag = buriePointEventReqDto.getFlag();
				
				if (flag != null) {

					if (flag == Constant.BURIED_FLAG_SUCCESS) {
						isUpdate = false;

					} else {
						isUpdate = true;
					}
				}else{
					isUpdate = true;
				}
			}else{
				isUpdate = false;
				
			}
			
			if(!isUpdate){
				
				buriePointEventReqDto = new BuriePointEventReqDto();
				
				buriePointEventReqDto.setUid(UserUtil.getUserId());
				
				buriePointEventReqDto.setEvent(Constant.BURIED_GAME_DOWNLOAD);
				
				BuriedPointDLData buriedPointDLData = new BuriedPointDLData();
				buriedPointDLData.setGameId(gameItem.getId());
				buriedPointDLData.setFormat(gameItem.getFormat());
				
				buriePointEventReqDto.setData(JSON.toJSONString(buriedPointDLData));
				
				long timeL = System.currentTimeMillis();
				String timeStr = DateTimeUtil.toDateTimeString(timeL);
				buriePointEventReqDto.setEvent_time(timeStr);
				
				buriePointEventReqDto.setStart_time(timeL);
				
				buriePointEventReqDto.setMode(ConstantURL.BURIED_MODE);
				
				buriePointEventReqDto.setClcItemId(clcItem.get_id());
				
				BuriePointEventReqDto.saveOrUpdate(buriePointEventReqDto);
				
			}
			
		}


		List<String> urlList = GameUrls(gameItem);
		
		String savePath = getRootPath(gameItem);
		
		DownloadTask task = new DownloadTask(gameItem,savePath,urlList);
		tasks.put(gameItem.getId(), task);
		task.setReTry(0);
		task.setMaxRetry(FailtRetry);
		DownloadBatchUrl.getInstants().addTask(task);
		
		//耗时
		gameDownNotify(gameItem);
	
	}
	
	
	static public boolean isDownloadWaiting(GameItem item){
		if(item!=null&&tasks.containsKey(item.getId())){
			
			DownloadTask task = tasks.get(item.getId());
			
			return task.isWaiting();
			
		}
		
		
		return true;
		
	}
	
	/**
	 * 取消所有正在下载Item
	 */
	static public void cancelAllDownloading(){
		 for (Map.Entry<Integer, DownloadTask> task : tasks.entrySet()) {
			System.out.println("key= " + task.getKey() + " and value= " + task.getValue());
			//Integer key = task.getKey();
			DownloadTask value = task.getValue();
			value.setDownloadState(DownloadTask.DownloadCancel);
			DownloadBatchUrl.getInstants().removeTask(value);
			//tasks.remove(key);
		}
		 tasks.clear();
	}
	
	/**
	 * 取消下载
	 * @param item
	 */
	static public void cancelDownload(GameItem item){
		
		MyLog.e(TAG, "cancelDownload..");
		
		synchronized (lock) {
			
			
			if(item!=null&&tasks.containsKey(item.getId())){
				
				DownloadTask task = tasks.get(item.getId());
				
				task.setDownloadState(DownloadTask.DownloadCancel);
				
				DownloadBatchUrl.getInstants().removeTask(task);
				
				tasks.remove(item.getId());
			}
		}
	}
	
	/**
	 * 暂停下载
	 * @param item
	 */
	public static void pauseDownload(GameItem item){
		
		synchronized (lock) {
			
			if(item!=null&&tasks.containsKey(item.getId())){
				
				DownloadTask task = tasks.get(item.getId());
				
				task.setDownloadState(DownloadTask.DownloadPause);
				
				DownloadBatchUrl.getInstants().removeTask(task);
				
				tasks.remove(item.getId());
			}
		}
		
	}



	static public int getDownloadProgress(GameItem item) {
		synchronized (lock) {
			if (item != null) {
				DownloadTask task = tasks.get(item.getId());
				if (task != null)
					return task.getProgress();
			}
		}
		return -1;
	}

	static public long getDownloadedBytes(GameItem item) {
		synchronized (lock) {
			if (item != null) {
				DownloadTask task = tasks.get(item.getId());
				if (task != null)
					return task.getDoneLen();
			}
		}
		return -1;
	}
	
    public static int getDownloadSpeed(){
    	return DownloadTask.getSpeed();
    }
    
//    public static String getDownloadSpeedTip(GameItem gameItem){
//    	
//    	int speed = getDownloadSpeed();
//    	
//    	StringBuffer sb = new StringBuffer();
//    	
//    	boolean isNetAvailable = NetworkUtils.isNetworkAvailable(VRApplication.getAppContext());
//    	
//    	MyLog.d(TAG, "isNetAvailable : " + isNetAvailable);
//    	
// 	if(!isNetAvailable){
//    		
// 		sb.append(Constant.SYMBOL_INTHEBAR);
// 		
// 		sb.append("\t\t");
// 		
// 		sb.append(0 + Constant.KB_PS);
// 		
// 		return sb.toString();
// 		
//    	}
// 	
//    	if(speed == 0){
//    		
//    		sb.append(Constant.SYMBOL_INTHEBAR + "\t");
//    		
//    	}else{
//    		
//    		sb.append(getDownloadRemailTime(gameItem));
//    		
//    	}
//    	
//    	sb.append("\t");
//    	
//    	MyLog.d(TAG, "download speed tip : " + sb.toString());
//    	
//    	if(speed < 1000){
//    		
//    		sb.append(speed + Constant.KB_PS);
//    		
//    	}else{
//    		int speedM = speed/1000;
//    		int speedK = (speed-speedM*1000)/100;
//    		sb.append(speedM+"."+speedK + Constant.MB_PS);
//    		
//    	}
//    	
//    	return sb.toString();
//    	
//    }
    
	public static String getDownloadSpeedStr() {
		int speed = getDownloadSpeed();
		
		StringBuffer sb = new StringBuffer();
		
		boolean isNetAvailable = NetworkUtils.isNetworkAvailable(VRApplication
				.getAppContext());

		if (!isNetAvailable) {

			sb.append(0 + Constant.KB_PS);

			return sb.toString();

		}
		
    	if(speed < 1000){
    		
    		sb.append(speed + Constant.KB_PS);
    		
    	}else{
    		int speedM = speed/1000;
    		int speedK = (speed-speedM*1000)/100;
    		sb.append(speedM+"."+speedK + Constant.MB_PS);
    		
    	}
    	
    	return sb.toString();
	}
    
//    public static String getDownloadRemailTime(GameItem gameItem){
//    	
//    	CollectionItem clcItem = CollectionItem.query(gameItem.getId());
//    	if(clcItem == null)return "";
//    	
//    	long totalLen = clcItem.getTotalLen();
//    	
//    	long downloadedLen = getGameDoneSize(gameItem);
//    	
//    	
//    	//因为totalLen单位为byte,速度又是kb，所以要把remainLen转换为kb
//    	long remainLen = (totalLen - downloadedLen)/Constant.SPEED_CONVERSION_UNIT;
//    	
//    	int downloadSpeed = getDownloadSpeed();
//    	
//    	long remainTime = remainLen / (downloadSpeed==0?1:downloadSpeed);
//    	
//    	MyLog.d(TAG,"remainTime : " + remainTime + "remainLen : " + remainLen + " totalLen : " + totalLen);
//    	
//    	String remainStr = DateTimeUtil.getTime(Integer.parseInt(String.valueOf(remainTime)));
//    	
//    	MyLog.d(TAG, "remainStr : " + remainStr);
//    	
//    	return remainStr;
//    }
    
//    private static long getTotalLengthMBLong(GameItem gameItem){
//    	long totalLen = gameItem.getSize()/Constant.BYTE_CONVERSION_MB;
//    	MyLog.d(TAG, "totalLen : " + totalLen);
//    	return totalLen;
//    }
//    
//    public static long getDownloadedLengthMB(GameItem gameItem){
//    	
//    	long downloadedLen = getGameDoneSize(gameItem)/Constant.BYTE_CONVERSION_MB;
//    	
//    	MyLog.d(TAG, "downloadedLen : " + downloadedLen);
//    	
//    	return downloadedLen;
//    }
//    
//    public static String getTotalLengthMBStr(GameItem gameItem){
//    	
//    	return String.valueOf(getTotalLengthMBLong(gameItem)) + Constant.MB;
//    	
//    }
//    
//    public static String getRatioLengthMB(GameItem gameItem){
//    	long totalLen = getTotalLengthMBLong(gameItem);
//    	long downloadedLen = getDownloadedLengthMB(gameItem);
//    	return downloadedLen + Constant.MB + "/" + totalLen + Constant.MB;
//    	
//    }
    
    public static String getDownloadedLengthStr(GameItem gameItem){
    	return FileConvertUtil.getMbGbFileSize(getGameDoneSize(gameItem));
    }
    
    public static String getTotalLengthStr(GameItem gameItem){
    	return FileConvertUtil.getMbGbFileSize(gameItem.getSize());
    }
    
   public static String getRatioLengthStr(GameItem gameItem){
   	return getDownloadedLengthStr(gameItem) + "/" + getTotalLengthStr(gameItem);
    }
    
    public static long getGameDoneSize(GameItem item){
        List<String> urlList = GameUrls(item);
        String savePath = getRootPath(item);
        long size = 0;
        for (String fname:urlList){
          String fileName = savePath+File.separator+FileUtils.getFileName(fname);
          String fileNameTmp = savePath+File.separator+FileUtils.getFileName(fname)+".tmp";
          
          File file = new File(fileName);
          if(file != null && file.exists()){
        	  size += file.length();
          }else{
        	  File fileTimp = new File(fileNameTmp);
        	  if(fileTimp != null && fileTimp.exists())
        		  size += fileTimp.length();
          }
        }
        return size;
      }
    
	
	/**
	 * 正在下载的重新下载
	 */
	public static void reDownloadGame(){
		
		MyLog.d(TAG, "reDownloadGame...");
		
		List<CollectionItem> clcItemList = CollectionItem.getAllNotDownloadedCollectionItems();
		
		if(clcItemList==null){
			return;
		}
		
		MyLog.d(TAG, "clcItemList " + clcItemList.toString());
		
		List<Integer> ids = new ArrayList<Integer>();
		
		
		for(CollectionItem clcItem:clcItemList){
			
			int state = clcItem.getDownloadState();
			if(state==CollectionItem.DownloadDoing||state==CollectionItem.DownloadError || state==CollectionItem.DownloadPause){
				
				
				
				ids.add(clcItem.getGameId());	
				
				MyLog.d(TAG, "ids " + ids);
				
			}
			
		}
		
		List<GameItem> gameItemList = GameItem.getGameListByIds(ids);
		
		if(gameItemList==null){
			
			return;
		}
		
		MyLog.d(TAG, "gameItemList " + gameItemList.toString());
		
		Collections.reverse(gameItemList);
		
		GameUpgradeUtils gameupdate = GameUpgradeUtils.getInstance();
		gameupdate.updateConfigDownloading(gameItemList);
			
	}
	

	

	
	
	private static HashMap<String, GameDdNotifyCallback> gameDdNotifyCenter = new HashMap<String,GameDdNotifyCallback>();
	
	/**
	 * 设置开始下载回调
	 * @param callback
	 * @param param
	 */
	public static void setGameDdNotify(GameDdNotifyCallback callback,String key){
		
		synchronized (nLock) {
			
			if(callback==null){
				
				gameDdNotifyCenter.remove(key);
				
			}else{
				
				gameDdNotifyCenter.put(key,callback);
			}
			
			
			
		}
	

		
	}
	
	/**
	 * 通知下载
	 */
	private static void gameDownNotify(GameItem gameItem){
		
		synchronized (nLock) {
			
			for(String key:gameDdNotifyCenter.keySet()){
				
				GameDdNotifyCallback notify = gameDdNotifyCenter.get(key);
				
				if(notify!=null){
					
					notify.startDownload(gameItem);
				}
				
			}
		
		}
		
		
	}
	
	//反馈下载进度
	public static void involkeGameProgress(Object params,int progress,int downloadState){
		synchronized (proLock) {
			
			for(String key:progressNotifies.keySet()){
				
				DownloadCallBack downloadCallback = progressNotifies.get(key);
				
				if(downloadCallback!=null){
					
					downloadCallback.progress(params, progress, downloadState);
				}
				
			}
			
		}
	}
	
	
	
	//设置下载进度回调
	public static void setGameProgressNotify(DownloadCallBack callBack, String key){
		synchronized(proLock) {
			if (callBack == null)
				progressNotifies.remove(key);
			else
				progressNotifies.put(key, callBack);
		}
	}
	
	//下载进度回调
	private static final Object proLock = new Object();
	
	//回调
	private static Map<String, DownloadCallBack> progressNotifies = new HashMap<String, DownloadCallBack>();
	
	//下载进度锁
	private static final Object dwLock = new Object();
	
	//存储下载进度 用于初始化
	private static Map<Integer,Integer> downProgress = new HashMap<Integer, Integer>();
	
	
	/**
	 * 获取初始化时的下载进度
	 * @param gameItem
	 * @return
	 */
	public static int getInitProgress(GameItem gameItem){
		
		int progress = getRunningProgress(gameItem.getId());
		MyLog.e(TAG, "getRunningProgress ： " + progress);
		if(-1==progress){
			
			CollectionItem clcItem = CollectionItem.query(gameItem.getId());
			
			if(clcItem==null){
				MyLog.e(TAG, "clcItem == null");
				return 0;
			}
			
			long totalLen = clcItem.getTotalLen();
			
			if(totalLen==0){
				MyLog.e(TAG, "totalLen == 0");
				return 0;
			}
			
			long curLen = 0;
			
			for(String res:GameRes(gameItem)){
				
				String savePath = getRootPath(gameItem)+"/"+res;
				
				File file = new File(savePath);
				
				if(file.exists()){
					
					curLen += file.length();
					
				}else{
					
					file = new File(savePath+".tmp");
					
					if(file.exists()){
						
						curLen += file.length();
					}
					
				}
					
			}
			
			
			
			progress = (int) (curLen*100/totalLen);
			
			MyLog.e(TAG, "caculat progress ： " + progress);
			
			if(progress>=100){
				
				progress = 0;
			}
			
			MyLog.e(TAG, "caculat progress 11： " + progress);
			
			//更新运行时进度
			setRunningProgresss(gameItem.getId(), progress);
				
			
		}
		
		if(progress>=100){
			
			progress = 0;
		}		
		return progress;
	}
	
	/**
	 * 获取运行时进度
	 * @param gameItem
	 * @return
	 */
	private static int getRunningProgress(int gameId){
		
		int progress = -1;
		
		synchronized (dwLock) {
			
			if(downProgress.containsKey(gameId)){
				
				progress = downProgress.get(gameId);
			}
		}
		
		return progress;
	}
	
	public static void setRunningProgresss(int gameId,int progress){
		
		synchronized (dwLock) {
			if(progress > 0){
				downProgress.put(gameId, progress);
			}
		}
	}
	
	/**
	 * 删除进度
	 * @param gameId
	 */
	public static void rmRunningProgress(int gameId){
		
		synchronized (dwLock) {
			
			downProgress.remove(gameId);
		}
	}
	
	public static void sortFavoritesGames(List<GameItem> gameList){
		if (gameList == null || gameList.size() == 0)
			return;
		List<GameItem> waiting = new ArrayList<GameItem>();
		List<GameItem> pause = new ArrayList<GameItem>();
		//List<GameItem> errors = new ArrayList<GameItem>();
		List<GameItem> none = new ArrayList<GameItem>();
		GameItem nowDownloading = null;
		for (GameItem item: gameList){
			CollectionItem citem = CollectionItem.query(item.getId());
			if (citem == null)
				continue;
			if (citem.getDownloadState() == CollectionItem.DownloadDoing && !GameDownload.isDownloadWaiting(item)){
				nowDownloading = item;
				continue;
			}
			if (citem.getDownloadState() == CollectionItem.DownloadDoing ||
					citem.getDownloadState() == CollectionItem.DownloadError){
				waiting.add(item);
			}else if (citem.getDownloadState() == CollectionItem.DownloadPause){
				pause.add(item);
			}else{
				none.add(item);
			}
		}
		gameList.clear();
		if (nowDownloading != null)
			gameList.add(nowDownloading);
		if (!waiting.isEmpty())
			gameList.addAll(waiting);
		if (!pause.isEmpty())
			gameList.addAll(pause);
		if (!none.isEmpty())
			gameList.addAll(none);
	}
	
}
